package pl.edu.mimuw.irs.rcp.wizard;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;

import pl.edu.mimuw.irs.core.model.analysis.Report;
import pl.edu.mimuw.irs.core.model.analysis.workflow.AnalysisWorkflow;
import pl.edu.mimuw.irs.core.model.design.net.IRSWorkflow;
import pl.edu.mimuw.irs.core.model.design.resource.Resources;
import pl.edu.mimuw.irs.rcp.controller.editor.report.ReportEditor;
import pl.edu.mimuw.irs.rcp.controller.editor.report.ReportEditorInput;
import pl.edu.mimuw.irs.rcp.controller.editor.simulation.SimulationEditor;
import pl.edu.mimuw.irs.rcp.controller.editor.simulation.SimulationEditorInput;
import pl.edu.mimuw.irs.rcp.controller.editor.workflow.IRSWorkflowEditor;
import pl.edu.mimuw.irs.rcp.persistence.PersistenceManager;
import pl.edu.mimuw.irs.rcp.util.Logger;
import pl.edu.mimuw.irs.rcp.util.MessageCode;
import pl.edu.mimuw.irs.rcp.util.UITexts;
import pl.edu.mimuw.irs.rcp.wizard.generator.GeneratorModel;
import pl.edu.mimuw.irs.rcp.wizard.generator.GeneratorPage;

public class GeneratorWizard extends Wizard implements INewWizard {
	
	// *** Attributes

	//private IWorkbench workbench;
	//private IStructuredSelection selection;
	private GeneratorPage generatorPage;
	//private ResourcesPage resourcesPage;
	private GeneratorModel generatorModel;
	public GeneratorModel getGeneratorModel() {
		if (generatorModel == null) generatorModel = new GeneratorModel();
		return generatorModel;
	}

	// *** Methods
	
	@Override
	public void init(IWorkbench workbench, IStructuredSelection selection) {
		this.generatorModel = new GeneratorModel();
		//this.workbench = workbench;
		//this.selection = selection;
		
		this.setWindowTitle(UITexts.get(MessageCode.PROJECT_WIZARD_NAME));
	}
	
	@Override
	public IWizardPage getStartingPage() {
		return generatorPage;
	}
	
	@Override
	public void addPages() {
		 generatorPage = new GeneratorPage();
	     addPage(generatorPage);
		 //resourcesPage = new ResourcesPage();
	     //addPage(resourcesPage);
	}
	
	@Override
	public boolean canFinish() {
		return generatorPage.isPageComplete();
	}
	
	
	
	@Override
	public boolean performFinish()  {
		generatorPage.saveDataToModel();
		
		/*
		 * Getting currently edited project.
		 */
		IWorkbench workbench = PlatformUI.getWorkbench();
		IEditorPart editor = (IRSWorkflowEditor) workbench.getActiveWorkbenchWindow().getActivePage().getActiveEditor();
		IEditorInput input = editor.getEditorInput();
		IFile file = null;
		if (input instanceof IFileEditorInput) {
			file = ((IFileEditorInput)input).getFile();
		}
		if (file == null)
			return false;
		
		IProject project = file.getProject();
		if (project == null) return false;
		/*
		 * Getting editors inputs to create analysis workflow.
		 */
		
		// XXX : ask if save editors
		IRSWorkflow workflow = null;
		Resources resources = null;
		PersistenceManager manager;
		try {
			manager = PersistenceManager.getInstance(input);
			if (manager == null) throw new Exception(input.toString());
			project = manager.getProject();
		} catch (Exception e) {
			Logger.handle(MessageCode.PERSISTENCE_MANAGER_PROBLEM, e, input.getName());
			return false;
		}
		try {
			workflow = manager.getWorkflow();
			if (manager == null) throw new Exception(input.toString());
		} catch (Exception e) {
			Logger.handle(MessageCode.WORKFLOW_LOAD_DESERIALIZE_PROBLEM, e, input.getName());
			return false;
		}
		try {
			resources = manager.getResources();
			if (resources == null) throw new Exception(input.toString());
		} catch (Exception e) {
			Logger.handle(MessageCode.RESOURCES_LOAD_DESERIALIZE_PROBLEM, e, input.getName());
			return false;
		}
		
		/* Got inputs - creating analysis workflow */
		AnalysisWorkflow analysisWorkflow = new AnalysisWorkflow(workflow, resources);
		
		/* Generator part */
//		GeneratorEditorInput generatorInput = new GeneratorEditorInput(analysisWorkflow);
//
//		try {
//			/*HandlerUtil.getActiveWorkbenchWindow(event).getActivePage()
//					.openEditor(analysisInput, AnalysisWorkflowEditor.ID);*/
//			editor.getSite().getPage().openEditor(generatorInput, GeneratorEditor.ID);
//		} catch (PartInitException e) {
//			Logger.handle(MessageCode.ANALYSIS_CREATE_PROBLEM, e, GeneratorEditor.ID);
//			return false;
//		}
		/* End of generator part */
		
		Report report = createReport(analysisWorkflow, editor);
		ReportEditorInput reportInput = new ReportEditorInput(report);
		
		SimulationEditorInput witnessInput = new SimulationEditorInput(workflow,
				analysisWorkflow, report, project);
		
		try {
			/*HandlerUtil.getActiveWorkbenchWindow(event).getActivePage()
					.openEditor(analysisInput, AnalysisWorkflowEditor.ID);*/
			editor.getSite().getPage().openEditor(reportInput, ReportEditor.ID);
			editor.getSite().getPage().openEditor(witnessInput, SimulationEditor.ID);
		} catch (PartInitException e) {
			Logger.handle(MessageCode.ANALYSIS_CREATE_PROBLEM, e, ReportEditor.ID);
			return false;
		}
		
		return true;
		
	}

	private Report createReport(final AnalysisWorkflow analysisWorkflow, IEditorPart editor) {
		
		ProgressMonitorDialog dialog = new ProgressMonitorDialog(editor.getSite().getShell());
		final Report report = new Report(analysisWorkflow);
		try {
			dialog.run(true, true, new IRunnableWithProgress(){
			    public void run(IProgressMonitor monitor) {
			        monitor.beginTask(UITexts.get(MessageCode.ANALYSIS_WORKING_PROGRESS), getGeneratorModel().runs);
			        report.generate(monitor, getGeneratorModel().runs);
			        monitor.done();
			    }
			});
		} catch (InvocationTargetException e) {
			Logger.handle(MessageCode.ANALYSIS_CREATE_PROBLEM, e);
		} catch (InterruptedException e) {
			Logger.handle(MessageCode.ANALYSIS_CREATE_PROBLEM, e);
		}
//		
		
		return report;
	}
}
